#ifndef _CODECPARAMSSERIALIZER_H
#define _CODECPARAMSSERIALIZER_H
#include <vector>
#include <cstring>
#include <cstdint>

extern "C" {
#include <libavcodec/avcodec.h>
}

class CodecParamsSerializer {
public:
    // 序列化 AVCodecParameters 到字节数组
    static std::vector<uint8_t> serialize(const AVCodecParameters* params) {
        std::vector<uint8_t> data;
        
        // 添加基本参数（所有类型都需要）
        add_int(data, params->codec_type);
        add_int(data, params->codec_id);
        add_int(data, params->format);
        
        // 根据媒体类型添加特定参数
        if (params->codec_type == AVMEDIA_TYPE_VIDEO) {
            // 视频特有参数
            add_int(data, params->width);
            add_int(data, params->height);
        } else if (params->codec_type == AVMEDIA_TYPE_AUDIO) {
            // 音频特有参数
            add_int(data, params->sample_rate);
            add_int(data, params->channels);
            add_int64(data, params->channel_layout);
            add_int(data, params->frame_size);
        }
        
        
        // 添加扩展数据（所有类型都需要）
        add_int(data, params->extradata_size);
        if (params->extradata_size > 0) {
            data.insert(data.end(), 
                        params->extradata, 
                        params->extradata + params->extradata_size);
        }
        
        return data;
    }

    // 从字节数组反序列化到 AVCodecParameters
    static AVCodecParameters* deserialize(const uint8_t* data, size_t size) {
        AVCodecParameters* params = avcodec_parameters_alloc();
        if (!params) return nullptr;
        
        const uint8_t* ptr = data;
        size_t remaining = size;
        
        // 读取基本参数
        params->codec_type = (AVMediaType)read_int(ptr, remaining);
        params->codec_id = (AVCodecID)read_int(ptr, remaining);
        params->format = read_int(ptr, remaining);
        
        // 根据媒体类型读取特定参数
        if (params->codec_type == AVMEDIA_TYPE_VIDEO) {
            // 视频特有参数
            params->width = read_int(ptr, remaining);
            params->height = read_int(ptr, remaining);
        } else if (params->codec_type == AVMEDIA_TYPE_AUDIO) {
            // 音频特有参数
            params->sample_rate = read_int(ptr, remaining);
            params->channels = read_int(ptr, remaining);
            params->channel_layout = read_int64(ptr, remaining);
            params->frame_size = read_int(ptr, remaining);
        }
        
        
        // 读取扩展数据
        params->extradata_size = read_int(ptr, remaining);
        if (params->extradata_size > 0 && 
            remaining >= (size_t)params->extradata_size) {
            
            params->extradata = (uint8_t*)av_malloc(params->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
            if (params->extradata) {
                memcpy(params->extradata, ptr, params->extradata_size);
                memset(params->extradata + params->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
                ptr += params->extradata_size;
            } else {
                params->extradata_size = 0;
            }
        }
        
        return params;
    }

private:
    // 辅助函数：添加整数到字节数组
    static void add_int(std::vector<uint8_t>& data, int value) {
        const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
        data.insert(data.end(), p, p + sizeof(int));
    }
    
    // 辅助函数：添加64位整数到字节数组
    static void add_int64(std::vector<uint8_t>& data, int64_t value) {
        const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
        data.insert(data.end(), p, p + sizeof(int64_t));
    }
    
    // 辅助函数：从字节数组读取整数
    static int read_int(const uint8_t*& ptr, size_t& remaining) {
        if (remaining < sizeof(int)) return 0;
        int value = *reinterpret_cast<const int*>(ptr);
        ptr += sizeof(int);
        remaining -= sizeof(int);
        return value;
    }
    
    // 辅助函数：从字节数组读取64位整数
    static int64_t read_int64(const uint8_t*& ptr, size_t& remaining) {
        if (remaining < sizeof(int64_t)) return 0;
        int64_t value = *reinterpret_cast<const int64_t*>(ptr);
        ptr += sizeof(int64_t);
        remaining -= sizeof(int64_t);
        return value;
    }
};


#endif



